/*
 * Description: 聊天区
 * Author: wangyifei
 * DateCreated: 2024-06-06 19:08
 */

import { memo, useEffect, useMemo, useState, type MutableRefObject } from 'react';
import { Button, Drawer, Input, Popover, Upload, message, type UploadProps } from 'antd';
import { ChatContainerStyle, EmojiListStyle } from './style';
import { CommentOutlined, EllipsisOutlined } from '@ant-design/icons';
import { EmojiList } from '../../assets/emoji';
import { uploadFile } from '../../http/minio';
import { getFileMsgFmt } from '../../utils';
import { insertRecordItem, type InsertRecordParam } from '../../http/chatting-records';
import { insertGroupFile, type GroupFileParam } from '../../http/chatting-group-files';
import ChatContent from './ChatContent';
import Members from './Members';
import type { GroupRes } from '../../http/chatting-group';
import type { IWSData } from '../../BetterChat';

export type ChatContentRef = {
	refreshNewMsg: (data: IWSData) => void;
	clearMsg: () => void;
};
type ChatContainerProps = {
	charRef: MutableRefObject<ChatContentRef>;
	active: GroupRes;
	refreshGroupList: () => void;
	onDelGroup: () => void;
};
const ChatContainer = memo((props: ChatContainerProps) => {
	const { charRef, active, refreshGroupList, onDelGroup } = props;

	const [textInput, setTextInput] = useState('');
	const [sendLoading, setSendLoading] = useState(false);
	const [emojiOpen, setEmojiOpen] = useState(false);
	// 群成员窗口
	const [membersOpen, setMembersOpen] = useState(false);

	useEffect(() => {
		return () => setTextInput('');
	}, [active]);

	// 表情列表组件
	const emojiList = useMemo(
		() => (
			<EmojiListStyle>
				{EmojiList.map((item) => {
					return (
						<span
							key={item}
							className="emoji_item"
							onClick={() => {
								setTextInput((prev) => prev + item);
								setEmojiOpen(false);
							}}
						>
							{item}
						</span>
					);
				})}
			</EmojiListStyle>
		),
		[]
	);

	// 发送消息
	const sendMessage = async () => {
		if (!textInput) return;
		setSendLoading(true);
		const payload: InsertRecordParam = {
			groupId: active.id,
			msg: textInput,
			msgFmt: 0
		};
		await insertRecordItem(payload).finally(() => setSendLoading(false));
		setTextInput('');
	};

	// 上传文件
	const customRequest: UploadProps['customRequest'] = async (options) => {
		const { file } = options;
		if (Math.floor((file as File).size / 1024 / 1024) >= 200) {
			message.warning('文件大小需小于200M');
			return;
		}
		setSendLoading(true);
		const formData = new FormData();
		formData.append('file', options.file);
		const { data } = await uploadFile(formData);
		const groupFile: GroupFileParam = {
			groupId: active.id,
			fileExt: data.ext,
			fileName: data.name,
			filePath: data.path,
			fileSize: data.size,
			fileUrl: data.url
		};
		await insertGroupFile(groupFile);
		const msgFmt = getFileMsgFmt(data.ext);
		const payload: InsertRecordParam = {
			groupId: active.id,
			msg:
				msgFmt === 7
					? JSON.stringify({ name: data.name, url: data.url, size: data.size })
					: data.url,
			msgFmt
		};
		await insertRecordItem(payload).finally(() => setSendLoading(false));
	};

	return (
		<ChatContainerStyle>
			{active ? (
				<>
					<div className="header">
						<div className="title">{active.title}</div>
						<div className="handle">
							<EllipsisOutlined style={{ fontSize: 20 }} onClick={() => setMembersOpen(true)} />
						</div>
					</div>
					<div className="records">
						<ChatContent ref={charRef} active={active} />
					</div>
					<div className="input">
						<div className="toolbar">
							<ul className="base_icon">
								<Popover
									trigger="click"
									content={emojiList}
									open={emojiOpen}
									onOpenChange={setEmojiOpen}
								>
									<li className="iconfont emoji" onClick={() => setEmojiOpen(true)}>
										&#xe627;
									</li>
								</Popover>
								<Upload showUploadList={false} customRequest={customRequest}>
									<li className="iconfont file">&#xe61d;</li>
								</Upload>
							</ul>
						</div>
						<Input.TextArea
							className="textarea"
							bordered={false}
							value={textInput}
							onChange={(evt) => {
								const value = evt.target.value;
								setTextInput(value);
							}}
						/>
						<div className="input_enter">
							<Button size="small" type="primary" loading={sendLoading} onClick={sendMessage}>
								发送
							</Button>
						</div>
					</div>
				</>
			) : (
				<div className="empty">
					<CommentOutlined className="empty_icon" />
				</div>
			)}

			{/* 群信息 */}
			<Drawer
				destroyOnClose
				open={membersOpen}
				width={300}
				title="群成员"
				closable={false}
				getContainer={false}
				onClose={() => setMembersOpen(false)}
			>
				<Members
					open={membersOpen}
					groupInfo={active}
					onClose={() => setMembersOpen(false)}
					refreshGroupList={refreshGroupList}
					onDelGroup={onDelGroup}
				/>
			</Drawer>
		</ChatContainerStyle>
	);
});

export default ChatContainer;
